package com.yc.atm;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zwei
 * @create 2024-07-19 14:46
 */
public class BankServer {
    private static Logger logger=Logger.getLogger(BankServer.class.getName());

    public static void main(String[] args) throws IOException {
        //获取cpu的核心数
        int processors=Runtime.getRuntime().availableProcessors();
        //核心线程池的大小
        int corePoolSize=processors;
        int maxPoolSize=corePoolSize*2;
        //线程最大空闲时间
        long keepAliveTime=10;
        //时间单位
        TimeUnit unit=TimeUnit.SECONDS; //enum枚举  常量
        //阻塞队列  容量为2  最多允许放入两个空闲任务
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(200);
        //创建线程工厂
        ThreadFactory threadFactory=new NameThreadFactory();
        //线程池拒绝策略
        RejectedExecutionHandler handler=new MyIgnorePolicy();
        ThreadPoolExecutor executor=null;
        executor=new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);
        //预启动所有核心线程 提升效率
        executor.prestartAllCoreThreads();

        Bank b=new Bank();
        ServerSocket socket=new ServerSocket(12000);
        logger.info("银行服务器启动，监听"+socket.getLocalPort()+"端口");
        boolean flag=true;
        while (flag){
            Socket s=socket.accept();
            System.out.println("ATM客户端："+s.getRemoteSocketAddress()+"登陆了服务器");
            //商业项目必须用线程池
//            Thread t=new Thread(new BankTask(s,b));
//            t.start();
            BankTask task=new BankTask(s,b);
            //提交任务到线程池
            executor.submit(task);
        }
        executor.shutdown();
    }
    /**
     * 线程工厂
     */
    public static class NameThreadFactory implements ThreadFactory{
        //线程id  AtomicInteger  原子类
        //原子性  可见性  有序性
        private final AtomicInteger threadId=new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {
            Thread thread=new Thread(r,"线程-"+threadId.getAndIncrement());
            return thread;
        }
    }
    /**
     * 线程池拒绝策略
     */
    public static class MyIgnorePolicy implements RejectedExecutionHandler{
        private Logger logger=Logger.getLogger(MyIgnorePolicy.class.getName());
        @Override                         //被拒绝的任务          线程池对象
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            doLog(r,executor);
        }
        private void doLog(Runnable runnable,ThreadPoolExecutor executor){
            logger.error("线程池"+executor.toString()+runnable.toString()+"被拒绝执行");
        }
    }
}
